package com.xncoding.freemarker.utile;


import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.net.ssl.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


public class XmlTools
{
    private static Provider prvd=null;
    private static final SSLHandler simpleVerifier=new SSLHandler();
    private static SSLSocketFactory sslFactory;
    protected Log log = LogFactory.getLog(this.getClass());

    private String encoding = "UTF-8";

    // 这个是极证云里的调用部分
    public String send(String msg,String TransCode) throws Exception {
        OutputStream reqStream = null;
        InputStream resStream = null;
        HttpURLConnection request = null;
        String respText = null;
        byte[] postData;
        try {
            String sendUtl = "";//postUrl + customerCode;
            log.debug("发送极证云地址-----------" + sendUtl);
            log.debug("发送极证云报文-----------" + msg);
            postData = msg.getBytes(encoding);
//            request = XmlTools.createRequest(sendUtl, "POST", proxyHost, proxyPort, useProxy, connectTimeout, readTimeout);

            request.setRequestProperty("Content-type", "text/plain");
            request.setRequestProperty("Content-length", String.valueOf(postData.length));
            request.setRequestProperty("Keep-alive", "false");

            reqStream = request.getOutputStream();
            reqStream.write(postData);

            int resCode = 200;
            int responseCode = request.getResponseCode();
            if (resCode == responseCode) {
                resStream = request.getInputStream();
            } else {
                resCode = responseCode;
                resStream = request.getErrorStream();
            }
            respText = IOUtils.toString(resStream, encoding);
            log.debug("--"+resCode+TransCode+"--"+ "极证云返回结果" +"--"+ respText);
            if (resCode != 200) {
                throw new RuntimeException(respText);
            }
        } catch (Exception ex) {
            throw ex;
        } finally {
            XmlTools.close(reqStream);
            XmlTools.close(resStream);
            request.disconnect();
        }
        return respText;
    }

    /**
     * 目标地址统一全部http
     * proxyPort 为：
     * 9000, 代表目标地址https协议
     * 8000，代表目标地址http协议
     * @param strUrl  目标地址
     * @param strMethod 请求方式get podt
     * @param proxyIp  代理ip
     * @param proxyPort 代理端口
     * @param isProxy  是否需要代理
     * @param connectTimeout
     * @param readTimeout
     * @return
     * @throws Exception
     */
    public static HttpURLConnection createRequest(String strUrl, String strMethod,String proxyIp,int proxyPort,boolean isProxy,int connectTimeout,int readTimeout) throws Exception
    {
        URL url = new URL(strUrl );
        URLConnection conn =null;
        if(isProxy) {
            SocketAddress addr = new InetSocketAddress(proxyIp, proxyPort);
            Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
            conn = url.openConnection(proxy);
        }else {
            conn = url.openConnection();
        }

        conn.setDoInput(true);
        conn.setDoOutput(true);
        if (conn instanceof HttpsURLConnection)
        {
            HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
            httpsConn.setRequestMethod(strMethod);
            httpsConn.setSSLSocketFactory(XmlTools.getSSLSF());
            httpsConn.setHostnameVerifier(XmlTools.getVerifier());
        }
        else if (conn instanceof HttpURLConnection)
        {
            HttpURLConnection httpConn = (HttpURLConnection) conn;
            httpConn.setRequestMethod(strMethod);
        }
        conn.setConnectTimeout(connectTimeout);
        conn.setReadTimeout(readTimeout);
        return (HttpURLConnection)conn;
    }
    public static void close(InputStream c)
    {
        try
        {
            if(c!=null) c.close();
        }
        catch(Exception ex)
        {

        }
    }
    public static void close(OutputStream c)
    {
        try
        {
            if(c!=null) c.close();
        }
        catch(Exception ex)
        {

        }
    }
    private static class SSLHandler implements X509TrustManager,HostnameVerifier
    {
        private SSLHandler()
        {
        }

        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean verify(String arg0, SSLSession arg1)
        {
            return true;
        }
    }

    /**
     * 将ASCII字符串转换成十六进制数据
     *
     * @param len
     *            ASCII字符串长度
     * @param data_in
     *            待转换的ASCII字符串
     * @param data_out
     *            已转换的十六进制数据
     */
    private static void Ascii2Hex(int len, byte data_in[], byte data_out[])
    {
        byte temp1[] = new byte[1];
        byte temp2[] = new byte[1];
        for (int i = 0, j = 0; i < len; j++)
        {
            temp1[0] = data_in[i];
            temp2[0] = data_in[i + 1];
            if (temp1[0] >= '0' && temp1[0] <= '9')
            {
                temp1[0] -= '0';
                temp1[0] = (byte) (temp1[0] << 4);

                temp1[0] = (byte) (temp1[0] & 0xf0);

            }
            else if (temp1[0] >= 'a' && temp1[0] <= 'f')
            {
                temp1[0] -= 0x57;
                temp1[0] = (byte) (temp1[0] << 4);
                temp1[0] = (byte) (temp1[0] & 0xf0);
            }

            if (temp2[0] >= '0' && temp2[0] <= '9')
            {
                temp2[0] -= '0';

                temp2[0] = (byte) (temp2[0] & 0x0f);

            }
            else if (temp2[0] >= 'a' && temp2[0] <= 'f')
            {
                temp2[0] -= 0x57;

                temp2[0] = (byte) (temp2[0] & 0x0f);
            }
            data_out[j] = (byte) (temp1[0] | temp2[0]);

            i += 2;
        }

    }

    protected String replaceAll(String strURL, String strAugs)
    {

        // JDK1.3中String类没有replaceAll的方法
        /** ********************************************************** */
        int start = 0;
        int end = 0;
        String temp = new String();
        while (start < strURL.length())
        {
            end = strURL.indexOf(" ", start);
            if (end != -1)
            {
                temp = temp.concat(strURL.substring(start, end).concat("%20"));
                if ((start = end + 1) >= strURL.length())
                {
                    strURL = temp;
                    break;
                }

            }
            else if (end == -1)
            {
                if (start == 0)
                    break;
                if (start < strURL.length())
                {
                    temp = temp.concat(strURL.substring(start, strURL.length()));
                    strURL = temp;
                    break;
                }
            }

        }

        temp = "";
        start = end = 0;

        while (start < strAugs.length())
        {
            end = strAugs.indexOf(" ", start);
            if (end != -1)
            {
                temp = temp.concat(strAugs.substring(start, end).concat("%20"));
                if ((start = end + 1) >= strAugs.length())
                {
                    strAugs = temp;
                    break;
                }

            }
            else if (end == -1)
            {
                if (start == 0)
                    break;
                if (start < strAugs.length())
                {
                    temp = temp.concat(strAugs.substring(start, strAugs.length()));
                    strAugs = temp;
                    break;
                }
            }

        }

        /** **************************************************************** */
        return strAugs;
    }
    /**
     * 将十六进制数据转换成ASCII字符串
     *
     * @param len
     *            十六进制数据长度
     * @param data_in
     *            待转换的十六进制数据
     * @param data_out
     *            已转换的ASCII字符串
     */
    private static void Hex2Ascii(int len, byte data_in[], byte data_out[])
    {
        byte temp1[] = new byte[1];
        byte temp2[] = new byte[1];
        for (int i = 0, j = 0; i < len; i++)
        {
            temp1[0] = data_in[i];
            temp1[0] = (byte) (temp1[0] >>> 4);
            temp1[0] = (byte) (temp1[0] & 0x0f);
            temp2[0] = data_in[i];
            temp2[0] = (byte) (temp2[0] & 0x0f);
            if (temp1[0] >= 0x00 && temp1[0] <= 0x09)
            {
                (data_out[j]) = (byte) (temp1[0] + '0');
            }
            else if (temp1[0] >= 0x0a && temp1[0] <= 0x0f)
            {
                (data_out[j]) = (byte) (temp1[0] + 0x57);
            }

            if (temp2[0] >= 0x00 && temp2[0] <= 0x09)
            {
                (data_out[j + 1]) = (byte) (temp2[0] + '0');
            }
            else if (temp2[0] >= 0x0a && temp2[0] <= 0x0f)
            {
                (data_out[j + 1]) = (byte) (temp2[0] + 0x57);
            }
            j += 2;
        }
    }
    public static HostnameVerifier getVerifier()
    {
        return simpleVerifier;
    }
    public static synchronized SSLSocketFactory getSSLSF() throws Exception
    {
        if(sslFactory!=null) return sslFactory;
        SSLContext sc = prvd==null?SSLContext.getInstance("TLS"):SSLContext.getInstance("TLS");
        sc.init(null, new TrustManager[]{simpleVerifier}, null);
        sslFactory = sc.getSocketFactory();
        return sslFactory;
    }
}
